#pragma once
#include <iostream>
#include <pthread.h>
#include <signal.h>
#include <memory>
#include "TcpServer.hpp"
#include "ThreadPool.hpp"
#include "Protocol.hpp"
#include "Log.hpp"
#define PORT 8081
class HttpServer
{
private:
    int port;
    bool running;
    TcpServer *tcp_server;
    ThreadPool * thread_pool;

public:
    HttpServer(int _port = PORT)
        : port(_port)
        , running(true)
        ,tcp_server(nullptr)
        ,thread_pool(nullptr)
    {
    }
    ~HttpServer()
    {
        if (tcp_server || thread_pool)
        {
            if(tcp_server)
            delete tcp_server;
            if(thread_pool)
            delete thread_pool;
        }
    }
    void InitServer()
    {
        // 通过单例模式创建
        tcp_server = TcpServer::getInstance(port); //创建单例TcpServer对象的时候直接在单例函数内部就执行了初始化tcp服务器的函数
        thread_pool = ThreadPool::getInstance(); //创建单例的时候就直接在单例函数内部初始化线程池了
        signal(SIGPIPE,SIG_IGN); //忽略SIGPIPE信号，防止服务器正在向读端(浏览器)写数据时，读端退出就会向写端(服务器)发送SIGPIPE信号，服务器就会退出
        //signal()
    }
    void Loop()
    {
        //可以选择使用两个智能指针进行资源管理，也可以在~hTTPServer中对两个资源进行delete释放
        // std::shared_ptr<TcpServer> s1(tcp_server);
        // std::shared_ptr<ThreadPool> s2(thread_pool);
        LOG(INFO, "Loop begin");
        int listen_sock = tcp_server->Sock();
        while (running)
        {
            std::cout << "DEBUG：ERVER New Cycle" << std::endl;
            struct sockaddr_in client;
            socklen_t len = sizeof(client);
            int sock = accept(listen_sock, (sockaddr *)&client, &len);
            if (sock < 0)
            {
                continue;
            }
            LOG(INFO, "Get a new link");
            //服务器调用accept后会获取一个新的连接，然后用这个新的sock来构建线程池要执行的任务
            Task task(sock);
            thread_pool->PushTask(task);

            // pthread_t tid;
            // int *_sock = new int(sock);
            // pthread_create(&tid, nullptr, Entrance::HandleRequest, (void *)_sock);
            //pthread_detach(tid); // 分离线程
        }
    }
};